#!/usr/bin/env python

# Copyright (c) 2015-present, Facebook, Inc.
# All rights reserved.
#
# This source code is licensed under the license found in the LICENSE file in
# the root directory of this source tree.

import logging
import optparse
import os.path
import shutil
import subprocess
import sys
from datetime import datetime

# Set up the logging early on in the process.
logging.basicConfig(level=logging.INFO, format='%(message)s')

# Add the lib/ directory to $PYTHONPATH so library code can be imported.
sys.path.append(os.path.join(os.path.dirname(__file__), '../lib'))

from package_manager import NUCLIDE_PATH

# Parse the command-line arguments.
parser = optparse.OptionParser(usage='usage: %prog [options]',
                               description='Install Nuclide packages for development')

parser.add_option('--dev', action='store_true',
                  help='Target ~/.atom/dev/packages/ instead of ~/.atom/packages',
                  default=False)
parser.add_option('--no-atom', action='store_true', default=False,
                  help='Exclude packages that depend on Atom (implies --no-link)')
parser.add_option('--no-link', action='store_true', default=False,
                  help='Skip linking the "nuclide" package')
parser.add_option('--nuke', action='store_true', default=False,
                  help='Remove all Atom caches and state. '
                       'NOTE: Serialized state and stored session data (like login '
                       'tokens) will be lost, also Atom may be temporarily unresponsive '
                       'during the first load while the caches are rebuilt')
parser.add_option('--production', action='store_true', default=False,
                  help='Install only production dependencies')
parser.add_option('--verbose', action='store_true', default=False,
                  help='Verbose output from npm install')
parser.add_option('--fast', action='store_true', default=False,
                  help='Run faster by skipping a full re-install of node_modules')

options, args = parser.parse_args(sys.argv[1:])

try:
    from fb.pre_setup import fb_pre_setup
    disable_fb_update = not options.dev
    fb_pre_setup(disable_fb_update)
except ImportError as e:
    pass

# Don't do this by default as it destroys some saved user state.
if options.nuke:
    logging.info('Removing Atom caches...')
    # v8 module cache
    shutil.rmtree(os.path.expanduser('~/.atom/blob-store'), ignore_errors=True)
    # transpile cache
    shutil.rmtree(os.path.expanduser('~/.atom/compile-cache'), ignore_errors=True)
    # serialized state
    shutil.rmtree(os.path.expanduser('~/.atom/storage'), ignore_errors=True)
    # cookies, localstorage, etc.
    if sys.platform == 'darwin':
        shutil.rmtree(os.path.expanduser('~/Library/Application Support/Atom'), ignore_errors=True)
    else:
        shutil.rmtree(os.path.expanduser('~/.config/atom'), ignore_errors=True)

if options.verbose:
    logging.getLogger().setLevel(logging.DEBUG)

if not options.fast:
    # Remove pre-existing node_modules.
    node_modules_dir = os.path.join(NUCLIDE_PATH, 'node_modules')
    if os.path.isdir(node_modules_dir):
        logging.info('Removing %s...', node_modules_dir)
        shutil.rmtree(node_modules_dir)

# Install packages.
if options.no_atom:
    install_cmd = ['npm', 'install', '--ignore-scripts']
else:
    install_cmd = ['apm', 'install', '--ignore-scripts']
if options.production:
    install_cmd.append('--production')
if options.verbose:
    install_cmd.append('--verbose')

start_install = datetime.now()
logging.info('Running "%s" in %s...', ' '.join(install_cmd), NUCLIDE_PATH)
subprocess.check_call(install_cmd, cwd=NUCLIDE_PATH)
logging.info('"%s install" took %s seconds.',
             install_cmd[0], (datetime.now() - start_install).seconds)

# "apm link" will fail if "~/.atom/packages/nuclide" is a directory, and
# overwrite if it's a symlink.
if not options.no_link and not options.no_atom:
    logging.info('Linking nuclide...')
    apm_link_args = ['apm']
    apm_link_args.append('link')
    if options.dev:
        apm_link_args.append('--dev')
    apm_link_args.append(NUCLIDE_PATH)
    subprocess.check_call(apm_link_args, cwd=NUCLIDE_PATH)
